﻿using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using BoldBrick.Core.Logging;
using BoldBrick.OneIntranet.HR.DataObjects;
using BoldBrick.OneIntranet.HR.Properties;
using BoldBrick.OneIntranet.HR.Resources;
using BoldBrick.OneIntranet.HR.Utils;
using BoldBrick.SharePoint.CommonControls.DataObjects.Base;
using BoldBrick.SharePoint.CommonControls.Utils;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Linq;
using BoldBrick.SharePoint.CommonControls.Extensions;

namespace BoldBrick.OneIntranet.HR.FieldTypes
{
	/// <summary>
	/// Field control for <see cref="PositionLookupField"/> field type
	/// </summary>
	public class PositionLookupFieldControl : LookupField
	{
		private static readonly ILogger log = Logger.GetLogger(typeof (PositionLookupFieldControl));

		#region ------ Create Controls ------------------------------------------------------------

		public override object Value
		{
			get
			{
				return base.Value;
			}
			set
			{
				base.Value = value;
				RemoveFolders();
			}
		}

		protected override void CreateChildControls()
		{
			base.CreateChildControls();

			// not support for display mode
			if (this.ControlMode == SPControlMode.Display)
				return;

			CreateLoadDefaultsButton();

			if (this.ControlMode == SPControlMode.New)
			{
				RemoveFolders();
			}
		}

		private void CreateLoadDefaultsButton()
		{
			bool showDefaultButtonObj = this.Field.GetCustomProperty(Settings.Default.Field_PositionLookup_CustomProperty_ShowDefaultButton_Name, false);

			if (!showDefaultButtonObj)
				return;

			uint language = SPContext.Current.Web.Language;
			
			Button buttonLoad = new Button
			                    	{
			                    		Text = ResourceBuilder.GetResource("PositionLookupFieldControl_buttonLoad_Text", language)
			                    	};
			buttonLoad.Click += new EventHandler(buttonLoad_Click);
			this.Controls.Add(buttonLoad);
		}

		private void RemoveFolders()
		{
			DropDownList dropDownList = ControlHelper.GetControls<DropDownList>(this).FirstOrDefault();
			if (dropDownList == null)
			{
				log.Write(LogLevel.Error, "DropDownList not found.");
				return;
			}

			SPList list = GetList();
			if (list == null)
				return;

			List<ListItem> listItems = dropDownList.Items.OfType<ListItem>()
				.Where(item => Convert.ToInt32(item.Value) > 0)
				.ToList();

			// go through all items and remove all folders from list
			foreach (ListItem listItem in listItems)
			{
				int id;
				if (int.TryParse(listItem.Value, out id))
				{
					SPListItem spListItem = list.GetItemById(id);
					
					if (spListItem != null)
					{
						// remove folders
						if (spListItem.Folder != null)
						{
							dropDownList.Items.Remove(listItem);
						}
						else
						{
							// remove closed position
							if (PositionsHelper.IsClosedOnSet(spListItem))
							{
								// remove closed position from new form or not selected one
								if (this.ControlMode == SPControlMode.New || !this.ItemIds.Contains(spListItem.ID))
								{
									dropDownList.Items.Remove(listItem);
								}
							}
						}
					}
				}
			}
		}

		#endregion

		#region ------ Get Item IDs ---------------------------------------------------------------

		#endregion

		#region ------ Load Default Values --------------------------------------------------------

		/// <summary>
		/// Loads default value to other fields
		/// </summary>
		private void LoadDefaults()
		{
			if (this.Value == null)
				return;

			List<BaseFieldControl> fieldControls = ControlHelper.GetControls<BaseFieldControl>(this.Page);
			if (fieldControls.Count == 0)
			{
				log.Write(LogLevel.Error, "No 'BaseFieldControl' found on the page.");
				return;
			}

			int positionId;
			if (!int.TryParse(this.Value.ToString(), out positionId))
				return;


			SPList listPositions = GetList();
			if (listPositions == null)
			{
				log.Write(LogLevel.Error, "No 'Positions' list found.");
				return;
			}

			SPListItem positionSelected = listPositions.GetItemById(positionId);

			SetFieldControl(fieldControls, positionSelected, SiteColumns.SeniorityLevelLookupColumn);
			SetFieldControl(fieldControls, positionSelected, SiteColumns.EmploymentTypesLookupColumn);
		}

		/// <summary>
		/// Setups field control
		/// </summary>
		/// <param name="fieldControls">Field control collection</param>
		/// <param name="positionItem">Item from Positions list</param>
		/// <param name="column">Column to update</param>
		private static void SetFieldControl(List<BaseFieldControl> fieldControls, SPListItem positionItem, ListColumn column)
		{
			BaseFieldControl fieldControlToUpdate = fieldControls.FirstOrDefault(fieldControl => fieldControl.FieldName == column.InternalName && !(fieldControl is FormField));
			if (fieldControlToUpdate == null)
			{
				log.Write(LogLevel.Error, "Field control for '{0}' column not found.", column.InternalName);
				return;
			}
			
			fieldControlToUpdate.Value = positionItem[column.InternalName];
		}

		#endregion

		#region ------ Common Methods -------------------------------------------------------------

		/// <summary>
		/// Gets "Positions" list binded to field of this control
		/// </summary>
		/// <returns>Returns "Positions" list binded to field of this control</returns>
		private SPList GetList()
		{
			SPFieldLookup fieldLookup = this.Field as SPFieldLookup;
			if (fieldLookup == null)
				return null;

			using (SPWeb web = SPContext.Current.Site.OpenWeb(fieldLookup.LookupWebId))
			{
				Guid listPositionsId = new Guid(fieldLookup.LookupList);
				SPList listPositions = null;
				try
				{
					listPositions = web.Lists[listPositionsId];
				}
				catch (Exception ex)
				{
					log.Write(LogLevel.Error, ex, "Cannot obtain 'Positions' list in '{0}' web.", web.ServerRelativeUrl);
				}
				return listPositions;
			}
		}

		#endregion

		#region ------ Validation -----------------------------------------------------------------

		public override void Validate()
		{
			base.Validate();

			if (!this.Field.Required)
				return;

			if (this.Value == null || string.IsNullOrEmpty(this.Value.ToString()))
				this.IsValid = false;
		}

		#endregion

		#region ------ Events ---------------------------------------------------------------------

		private void buttonLoad_Click(object sender, EventArgs e)
		{
			LoadDefaults();


		}

		

		#endregion
	}
}
